
//  AppDelegate.m
//  XunMi
//
//  Created by MacBook on 2024/2/18.
//

#import "AppDelegate.h"
#import "XMHomeViewController.h"
#import "XMTabBarViewController.h"
#import "XMLoginViewController.h"
#import "XMNavigationController.h"
#import <TencentOpenAPI/TencentOpenApiUmbrellaHeader.h>
#import "XMUploadManager.h"
#import <OneLoginSDK/OneLoginSDK.h>
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#import <AdSupport/ASIdentifierManager.h>
#import "XMLanuchPlaceViewController.h"
#import "XMRCManager.h"
#import "XMRCDataSource.h"
#import "RCCall.h"
#import <UserNotifications/UserNotifications.h>
//#import "XMLocationManager.h"
#import "XMCustomSendMessage.h"
#import "XMInviteMessage.h"
#import "YHIAPManager.h"

@interface AppDelegate () <UIApplicationDelegate, UNUserNotificationCenterDelegate, RCIMConnectionStatusDelegate, RCIMReceiveMessageDelegate, RCIMMessageInterceptor>

@end

@implementation AppDelegate

+ (instancetype)sharedAppDelegate {
    return (AppDelegate *)[UIApplication sharedApplication].delegate;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    [MMKV initializeMMKV:nil logLevel:MMKVLogNone];
    [kMMKV setString:kRequestUrl forKey:kRequestUrlKey];
    [self versionCompatible];
    [self appLaunch];
    [self addNotification];
    [YHIAPManager sharedInstance];
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)appLaunch {
    XMLanuchPlaceViewController *vc = [[XMLanuchPlaceViewController alloc] initWithNibName:@"XMLanuchPlaceViewController" bundle:nil];
    self.window.rootViewController = [[XMNavigationController alloc] initWithRootViewController:vc];
    XMWeakSelf(self);
    vc.enterBlock = ^{
        XMStrongSelf(self);
        [self setupThirdPart];
        [self globalConfig];
    };
}

- (void)globalConfig {
    NSMutableDictionary *dic = @{}.mutableCopy;
    [YHNetworkManager.sharedInstance postWithUrl:@"api/auth/globalConfig" parameters:dic completeBlock:^(XMResponseTip * _Nonnull tip, id  _Nullable result) {
        if (tip.success) {
            XMAppConfigModel *model = [XMAppConfigModel mj_objectWithKeyValues:result];
            kGlobalVariables.appConfig = model;
            [self configAndEnterHome];
        }
    }];
}

- (void)versionCompatible {
    if (@available(iOS 15.0, *)) {
        [UITableView appearance].sectionHeaderTopPadding = 0;
    }
    
    if (@available(iOS 11, *)) {
        // iOS11 解决SafeArea的问题，同时能解决pop时上级页面scrollView抖动的问题
        [UIScrollView appearance].contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
        [UIScrollView appearance].contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
        [UIScrollView appearance].scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, 0, 0);
    }
    
    // 解决在iOS11上朋友圈demo文字收折或者展开时出现cell跳动问题
    [UITableView appearance].estimatedRowHeight = CGFLOAT_MIN;
    [UITableView appearance].estimatedSectionFooterHeight = CGFLOAT_MIN;
    [UITableView appearance].estimatedSectionHeaderHeight = CGFLOAT_MIN;
    [UITableView appearance].rowHeight = UITableViewAutomaticDimension;
}

- (void)setupThirdPart {
//    [[XMLocationManager sharedInstance] startLocation];
//    [NSObject addClassNamesToWhitelist:@[NSStringFromClass([UITextField class])]];

    [IQKeyboardManager sharedManager].previousNextDisplayMode = IQPreviousNextDisplayModeAlwaysHide;
    [IQKeyboardManager sharedManager].shouldResignOnTouchOutside = YES;
    //   [IQKeyboardManager sharedManager].enableAutoToolbar = YES;
    
    [[SDImageCodersManager sharedManager] addCoder:[SDImageWebPCoder sharedCoder]];
    
    [DDLog addLogger:[DDOSLogger sharedInstance]];
    // 添加DDFileLogger，日志语句将写入到一个文件中，默认路径在沙盒的Library/Caches/Logs/目录下，文件名为bundleid+空格+日期.log。
    DDFileLogger *fileLogger = [[DDFileLogger alloc] init];
    fileLogger.rollingFrequency = 60 * 60 * 24;
    fileLogger.logFileManager.maximumNumberOfLogFiles = 7;
    [DDLog addLogger:fileLogger];
    //    kGlobalVariables.uuidStr = [YHKeyChainStore getUUIDByKeyChain];
    [[XMUploadManager sharedInstance] setupCOSXMLShareService];
    // 设置日志开关，建议平常调试过程中打开，便于排查问题，上线时可以关掉日志
    [OneLoginPro setLogEnabled:NO];
    // 设置AppId，AppID通过后台注册获得，从极验后台获取该AppID，AppID需与bundleID配套
    [OneLoginPro registerWithAppID:@"36d1b4f70fb2914a491fcd73908f5d93"];
    
    [[RCIM sharedRCIM] initWithAppKey:kRongCloudAppKey option:nil];
}

- (void)configAndEnterHome {
    if (![NSString isEmpty:XMLoginManager.sharedInstance.rongToken] &&
        ![NSString isEmpty:XMLoginManager.sharedInstance.token]) {
        [self setupNeedToken];
        [self configRongIM];
        [self enterMainPage];
    } else {
        [self loginRootClearBadge:NO];
    }
}

- (void)enterMainPage {
    XMLog(@"当前用户融云Token:%@", XMLoginManager.sharedInstance.rongToken);
    XMLog(@"当前用户Token:%@", XMLoginManager.sharedInstance.token);
    XMTabBarViewController *tabbar = [[XMTabBarViewController alloc] init];
    CATransition *transition = [CATransition new];
    transition.duration = 0.75;
    transition.type = kCATransitionFade;
    [self.window.layer addAnimation:transition forKey:@""];
    self.window.rootViewController = tabbar;
    self.loginRoot = NO;
    
    RCUserInfo *currentUserInfo = [[RCUserInfo alloc] initWithUserId:XMLoginManager.sharedInstance.userId name:XMLoginManager.sharedInstance.nickName portrait:XMLoginManager.sharedInstance.avatar];
    [RCIM sharedRCIM].currentUserInfo = currentUserInfo;
    
    XMWeakSelf(self);
    [[XMRCManager sharedInstance] connectWithToken:XMLoginManager.sharedInstance.rongToken
                                         timeLimit:0
                                          dbOpened:^(RCDBErrorCode code) {
        XMLog(@"IM数据库打开:%@", code == 0 ? @"成功" : @"失败");
    }
                                           success:^(NSString *_Nonnull userId) {
        RCUserInfo *currentUserInfo = [[RCUserInfo alloc] initWithUserId:kUserModel.user_id name:kUserModel.nickname portrait:kUserModel.avatar.file_url];
        [RCIM sharedRCIM].currentUserInfo = currentUserInfo;
    }
                                             error:^(RCConnectErrorCode errorCode) {
        XMLog(@"融云链接失败: %@", @(errorCode));
        if (errorCode == RC_CONN_TOKEN_INCORRECT) {
            XMLog(@"IM无法连接到服务器");
        } else if (errorCode == RC_CONN_USER_BLOCKED) {
            XMLog(@"IM用户被封禁");
        }
        XMStrongSelf(self);
        [self logout];
    }];
}

- (void)setupNeedToken {
    // replyUsersListCompleteBlock
    // 用户信息
    NSMutableDictionary *dic = @{
    }.mutableCopy;
    [YHNetworkManager.sharedInstance postWithUrl:@"api/user/obtain" parameters:dic completeBlock:^(XMResponseTip * _Nonnull tip, id  _Nullable result) {
        if (tip.success) {
            XMUserModel *model = [XMUserModel mj_objectWithKeyValues:result];
            kUserModel = model;
        }
    }];
}

- (void)configRongIM {
    [[RCIM sharedRCIM] setConnectionStatusDelegate:self];
    [[RCIM sharedRCIM] setReceiveMessageDelegate:self];
    [[RCIM sharedRCIM] setMessageInterceptor:self];
    [RCIM sharedRCIM].enablePersistentUserInfoCache = YES;
    [RCIM sharedRCIM].userInfoDataSource = kXMRCDataSource;
    [[RCCoreClient sharedCoreClient] setAppVer:[XMUtil bundleShortVersionString]];
    
    [[RCCoreClient sharedCoreClient] setCheckDuplicateMessage:YES];
    
    [RCCoreClient sharedCoreClient].voiceMsgType = RCVoiceMessageTypeHighQuality;
    
    [RCCoreClient sharedCoreClient].logLevel = RC_Log_Level_None;
    
    
    [[RCIM sharedRCIM] registerMessageType:[XMCustomSendMessage class]];
    [[RCIM sharedRCIM] registerMessageType:[XMInviteMessage class]];
    
    //    [[RCIM sharedRCIM] registerMessageType:[YHChatGuardMessage class]];
    //    [[RCIM sharedRCIM] registerMessageType:[YHChatInviteGuardMessage class]];
    
    //    [[RCIM sharedRCIM] registerMessageType:[YHChatInviteSmashEggMessage class]];
    
    RCKitConfigCenter.ui.enableDarkMode = NO;
    RCKitConfigCenter.ui.globalConversationPortraitSize = CGSizeMake(48, 48);
    RCKitConfigCenter.ui.globalConversationAvatarStyle = RC_USER_AVATAR_CYCLE;
    RCKitConfigCenter.ui.globalNavigationBarTintColor = UIColor.whiteColor;
    //    RCKitConfigCenter.ui.globalMessagePortraitSize = CGSizeMake(28, 28);
    RCKitConfigCenter.ui.globalMessageAvatarStyle = RC_USER_AVATAR_CYCLE;
}

#pragma mark - 退出登录
- (void)logout {
    //    [JSHAREService cancelAuthWithPlatform:(JSHAREPlatformQQ)];
    //    [JSHAREService cancelAuthWithPlatform:(JSHAREPlatformWechatSession)];
    if (![NSString isEmpty:XMLoginManager.sharedInstance.rongToken] &&
        ![NSString isEmpty:XMLoginManager.sharedInstance.token]) {
        NSMutableDictionary *dic = @{}.mutableCopy;
        [YHNetworkManager.sharedInstance postWithUrl:@"api/user/logout" parameters:dic completeBlock:^(XMResponseTip * _Nonnull tip, id  _Nullable result) {
        }];
        [[RCIM sharedRCIM] logout];
        [[XMLoginManager sharedInstance] removeLoginData];
    }
    [self loginRootClearBadge:YES];
}

#pragma mark - 被动退出登录 不调用退出登录接口
- (void)passiveLogout {
    [self loginRootClearBadge:YES];
}

- (void)loginRootClearBadge:(BOOL)clearBadge {
    if (self.loginRoot) {
        return;
    }
    dispatch_async(dispatch_get_main_queue(), ^{
        if (clearBadge) {
            [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
        }
        self.window.rootViewController = [[XMNavigationController alloc] initWithRootViewController:[[XMLoginViewController alloc] initWithNibName:NSStringFromClass(XMLoginViewController.class) bundle:nil]];
        self.loginRoot = YES;
    });
}

#pragma mark - RCIMReceiveMessageDelegate
- (BOOL)interceptMessage:(RCMessage *)message {
    //    if ([message.senderUserId isEqualToString:kUserModel.user_id]) {
    //        return YES;
    //    }
    [self updateUnreadCount];
    if ([message.objectName isEqualToString:@"RC:CmdMsg"]) {
        RCCommandMessage *commandMessage = (RCCommandMessage *)message.content;
        if ([commandMessage.name isEqualToString:@"xunmi_logout"]) {
            [self logout];
        }
        if ([commandMessage.name isEqualToString:@"xunmi_muted"]) {
            [kNotificationCenter postNotificationName:@"xunmi_muted" object:nil];
        }
        //        if ([commandMessage.name isEqualToString:@"xyh_update"]) {
        //            [kNotificationCenter postNotificationName:kVersionUpdate object:nil];
        //        }
    }
    return NO;
}

- (BOOL)interceptWillSendMessage:(RCMessage *)message {
    
    return NO;
}

#pragma mark - RCIMConnectionStatusDelegate
#pragma mark - 网络状态变化。
- (void)onRCIMConnectionStatusChanged:(RCConnectionStatus)status {
    // 当前用户在其他设备上登录，此设备被踢下线
    if (status == ConnectionStatus_KICKED_OFFLINE_BY_OTHER_CLIENT) {
        [[RCIM sharedRCIM] logout];
        [[XMLoginManager sharedInstance] removeLoginData];
        [XMAlertHelper alertTitle:@"当前用户在其他设备上登录，此设备被踢下线"
                          message:nil
                      cancelTitle:nil
                        sureTitle:@"确定"
                     cancelAction:nil
                       sureAction:^{
            [self passiveLogout];
        }];
        
    } else if (status == ConnectionStatus_TOKEN_INCORRECT) {
        // Token无效
        [[RCIM sharedRCIM] logout];
        [[XMLoginManager sharedInstance] removeLoginData];
        [XMAlertHelper alertTitle:@"Token无效"
                          message:nil
                      cancelTitle:nil
                        sureTitle:@"确定"
                     cancelAction:nil
                       sureAction:^{
            [self passiveLogout];
        }];
    } else if (status == ConnectionStatus_DISCONN_EXCEPTION) {
        // 与服务器的连接已断开,用户被封禁
        [[RCIM sharedRCIM] logout];
        [[XMLoginManager sharedInstance] removeLoginData];
        [XMAlertHelper alertTitle:@"与服务器的连接已断开,用户被封禁"
                          message:nil
                      cancelTitle:nil
                        sureTitle:@"确定"
                     cancelAction:nil
                       sureAction:^{
            [self passiveLogout];
        }];
    } else if (status == ConnectionStatus_USER_ABANDON) {
        // 用户账号已销户，不再进行连接
        [[RCIM sharedRCIM] logout];
        [[XMLoginManager sharedInstance] removeLoginData];
        [XMAlertHelper alertTitle:@"用户账号已销户，不再进行连接"
                          message:nil
                      cancelTitle:nil
                        sureTitle:@"确定"
                     cancelAction:nil
                       sureAction:^{
            [self passiveLogout];
        }];
    }
}

#pragma mark - 添加通知
- (void)addNotification {
    // 广告 引导 跳过的通知
    // [kNotificationCenter addObserver:self selector:@selector(initAppData) name:kAppChangeRootVC object:nil];
    // 退出登录
    [kNotificationCenter addObserver:self selector:@selector(logout) name:@"xm_logout" object:nil];
    // Token失效
    [kNotificationCenter addObserver:self selector:@selector(tokenExpire) name:kTokenExpire object:nil];
}

#pragma mark - 注册通知
- (void)registerNotification:(NSDictionary *)launchOptions {
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert)
                          completionHandler:^(BOOL granted, NSError *_Nullable error) {
        if (!error) {
            XMLog(@"request authorization succeeded!");
        }
    }];
    [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings *_Nonnull settings) {
        XMLog(@"%@", settings);
    }];
    // 如果点击通知栏的远程推送时，App 已经被系统冻结，可使用下面方式获取：
    NSDictionary *remoteUserInfo = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
    if (remoteUserInfo) {
        // APP未启动，点击推送消息，iOS10下还是跟以前一样在此获取
    }
    center.delegate = self;
    [[UIApplication sharedApplication] registerForRemoteNotifications];
    [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
}

- (void)checkNotificationAuthorization {
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound)
                          completionHandler:^(BOOL granted, NSError *_Nullable error) {
        if (granted) {
            [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings *_Nonnull settings){
            }];
        }
    }];
}

#pragma mark - 接口Code400 token失效退出登录
- (void)tokenExpire {
    [[RCIM sharedRCIM] logout];
    [[XMLoginManager sharedInstance] removeLoginData];
    [self loginRootClearBadge:NO];
}

#pragma mark - 网络状态
- (void)monitorNetworkStatus {
    [[AFNetworkReachabilityManager sharedManager] startMonitoring];
    [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        switch (status) {
            case AFNetworkReachabilityStatusUnknown:
                break;
            case AFNetworkReachabilityStatusNotReachable:
                [MBProgressHUD showHUDMsg:@"网络链接已断开" toView:nil];
                break;
            case AFNetworkReachabilityStatusReachableViaWWAN:
                break;
            case AFNetworkReachabilityStatusReachableViaWiFi:
                break;
            default:
                break;
        }
    }];
}

#pragma mark - 进入前台更新未读消息数
- (void)updateUnreadCount {
    RCConnectionStatus status = [[RCCoreClient sharedCoreClient] getConnectionStatus];
    if (status != ConnectionStatus_SignOut) {
        [[RCCoreClient sharedCoreClient] getUnreadCount:@[
            @(ConversationType_PRIVATE),
            @(ConversationType_SYSTEM)
        ] completion:^(int count) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [UIApplication sharedApplication].applicationIconBadgeNumber = count;
                XMTabBarViewController *tabBar = (XMTabBarViewController *)[UIViewController currentViewController].tabBarController;
                [tabBar.tabBarView setBadgeNum:count];
            });
        }];
    }
}

#pragma mark - 统计推送打开率
- (void)recordLaunchOptions:(NSDictionary *)launchOptions {
    // 统计推送打开率1
    [[RCCoreClient sharedCoreClient] recordLaunchOptionsEvent:launchOptions];
    // 获取融云推送服务扩展字段1
    NSDictionary *pushServiceData = [[RCCoreClient sharedCoreClient] getPushExtraFromLaunchOptions:launchOptions];
    if (pushServiceData) {
        XMLog(@"该启动事件包含来自融云的推送服务");
        for (id key in [pushServiceData allKeys]) {
            XMLog(@"%@", pushServiceData[key]);
        }
    } else {
        XMLog(@"该启动事件不包含来自融云的推送服务");
    }
}

#pragma mark - UNUserNotificationCenterDelegate
#pragma mark - iOS10之后点击推送
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
    NSDictionary *userInfo = notification.request.content.userInfo;
    if ([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        XMLog(@"iOS10 收到远程通知");
        [[RCCoreClient sharedCoreClient] recordRemoteNotificationEvent:userInfo];
    } else {
        // 判断为本地通知
        XMLog(@"iOS10 收到本地通知");
    }
    // 在前台默认不显示推送，如果要显示，就要设置以下内容
    // 微信设置里-新消息通知-微信打开时-声音or振动  就是该原理
    // 需要执行这个方法，选择是否提醒用户，有Badge、Sound、Alert三种类型可以设置
    completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert);
}

#pragma mark - iOS10之后在后台 点击推送
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
    NSDictionary *userInfo = response.notification.request.content.userInfo;
    if ([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        XMLog(@"iOS10 收到远程通知");
        [[RCCoreClient sharedCoreClient] recordRemoteNotificationEvent:userInfo];
    } else {
        // 判断为本地通知
        XMLog(@"iOS10 收到本地通知");
    }
    completionHandler();
}

- (void)userNotificationCenter:(UNUserNotificationCenter *)center openSettingsForNotification:(nullable UNNotification *)notification {
    if (notification && [notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        // 从通知界面直接进入应用
    } else {
        // 从通知设置界面进入应用
    }
}

#pragma mark - UIApplicationDelegate
// 仅支持 iOS9 以上系统，iOS8 及以下系统不会回调
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
    //    if ([JSHAREService handleOpenUrl:url]) {
    //        return YES;
    //    }
    //
    //    if ([[YHSharetrace sharedInstance] handleSchemeLinkURL:url]) {
    //        return YES;
    //    }
    if ([TencentOAuth CanHandleOpenURL:url]) {
        return [TencentOAuth HandleOpenURL:url];
    }
    if ([WXApi handleOpenURL:url delegate:kWXApiManager]) {
        return YES;
    }
    
    return YES;
}


- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> *__nullable restorableObjects))restorationHandler API_AVAILABLE(ios(8.0)) {
    if ([WXApi handleOpenUniversalLink:userActivity delegate:kWXApiManager]) {
        return YES;
    }
    NSURL *url = userActivity.webpageURL;
    if (url && [TencentOAuth CanHandleUniversalLink:url]) {
        return [TencentOAuth HandleUniversalLink:url];
    }
    return YES;
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    [self getIDFA];
}

- (void)getIDFA {
    if (@available(iOS 14, *)) {
        [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
            if (status == ATTrackingManagerAuthorizationStatusAuthorized) {
                NSString *idfa = [[ASIdentifierManager sharedManager].advertisingIdentifier UUIDString];
                NSLog(@"idfa:%@", idfa);
                [kMMKV setString:idfa forKey:@"idfa"];
            } else {
                NSLog(@"请在设置-隐私-跟踪中允许App请求跟踪");
            }
        }];
    } else {
        if ([[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]) {
            NSString *idfa = [[ASIdentifierManager sharedManager].advertisingIdentifier UUIDString];
            NSLog(@"idfa:%@", idfa);
            [kMMKV setString:idfa forKey:@"idfa"];
        } else {
            NSLog(@"请在设置-隐私-广告中打开广告跟踪功能");
        }
    }
}

@end
